﻿namespace BM.Tools.WebControls.MForm.Controls.ValueHandlers
{
    using System;
    using System.ComponentModel;
    using System.Web.UI.WebControls;

    using BM.Tools.WebControls.MForm.Controls.Items;
    using BM.Tools.WebControls.MForm.Resources;

    /// <summary>
    /// An abstract control that binds the <see cref="LeafItem" /> control with a control that inherits from <see cref="ListControl" /> .
    /// </summary>
    /// <typeparam name="T">
    /// A type that inherits from <see cref="ListControl" /> .
    /// </typeparam>
    public abstract class ListControlValueHandler<T> : StandardWebControlValueHandler<T>, IListControlValueHandler
            where T : ListControl, new()
    {
        private bool emptyOptionFirst = true;

        private string emptyOptionText;

        /// <summary>
        /// Gets or sets a value indicating whether to use empty option at the beginning of the list items.
        /// </summary>        
        [DefaultValue(true)]
        public virtual bool EmptyOptionFirst
        {
            get
            {
                return emptyOptionFirst;
            }

            set
            {
                emptyOptionFirst = value;
            }
        }

        /// <summary>
        /// Gets or sets EmptyOptionText.
        /// </summary>               
        public string EmptyOptionText
        {
            get
            {
                if (emptyOptionText == null)
                {
                     return LanguageResource.Choose;
                }

                return emptyOptionText;
            }

            set
            {
                emptyOptionText = value;
            }
        }

        /// <summary>
        /// Gets ListControl.
        /// </summary>        
        public ListControl ListControl
        {
            get
            {
                if (Parent != null)
                {
                    EnsureChildControls();
                }

                return Control;
            }
        }

        /// <summary>
        /// Gets or sets Value.
        /// </summary>
        public override string Value
        {
            get
            {
                return Control.SelectedValue;
            }

            set
            {
                try
                {
                    Control.SelectedValue = value;
                }
                catch (ArgumentOutOfRangeException)
                {
                }
            }
        }

        /// <summary>
        /// Gets the text associated with the selected item
        /// </summary>
        protected override string DefaultViewModeControlValue
        {
            get
            {
                return ListControl.SelectedItem != null ? ListControl.SelectedItem.Text : ViewModeControlValue;
            }
        }

        /// <summary>
        /// Avoid exception if selected value does not match list
        /// </summary>
        public override void DataBind()
        {
            try
            {
                base.DataBind();
            }
            catch (ArgumentOutOfRangeException)
            {
            }
        }

        /// <summary>
        /// conditionally inserts the empty option item
        /// </summary>
        protected override void OnChildControlCreating()
        {
            if (EmptyOptionFirst && Owner != null && !Owner.Basis.IsDuringGeneration)
            {
                Control.Items.Insert(0, new ListItem(EmptyOptionText, string.Empty));
            }
        }

        /// <summary>
        /// Prepares the control, its css class and the child items
        /// </summary>
        protected override void PrepareControl()
        {
            base.PrepareControl();
            PrepareItems();
        }

        /// <summary>
        /// This method can be overriden to change list items.
        /// </summary>
        /// <param name="item">
        /// The list item.
        /// </param>
        protected virtual void PrepareItem(ListItem item)
        {
        }

        /// <summary>
        /// This method iterates through all the child items and runs the <see cref="PrepareItem" /> method
        /// </summary>
        protected virtual void PrepareItems()
        {
            foreach (ListItem item in Control.Items)
            {
                PrepareItem(item);
            }
        }

        private bool ShouldSerializeEmptyOptionText()
        {
            return EmptyOptionText != LanguageResource.Choose;
        }        
    }
}